package com.sgx.learning.luban.data_structure;

import com.sgx.learning.luban.data_structure.impl.Stack;

import java.util.Arrays;
import java.util.EmptyStackException;

public class ArrayStack<V> implements Stack<V> {

    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;

    static final Object[] DEFAULT_DATA = new Object[]{};

    private Object[] data;

    private int capacity;

    private int size = 0;

    public ArrayStack() {
        data = DEFAULT_DATA;
    }

    public ArrayStack(int capacity) {
        if(capacity <= 0) {
            data = DEFAULT_DATA;
        } else {
            this.capacity = capacity;
            data = new Object[this.capacity];
        }
    }

    @Override
    public boolean push(V value) {
        if(size == capacity) {
            resize();
        }
        data[size] = value;
        size++;
        return true;
    }

    @Override
    public V pop() {
        if(size() == 0) {
            throw new EmptyStackException();
        }
        int top = size() - 1;
        Object v = data[top];
        size--;
        return (V) v;
    }

    private void resize() {
        if(capacity == 0) {
            capacity = DEFAULT_INITIAL_CAPACITY;
        } else {
            capacity += capacity << 1;
        }
        this.data = Arrays.copyOf(this.data,capacity);
    }

    @Override
    public int size() {
        return this.size;
    }

    public static void main(String[] args) {
        ArrayStack<Integer> stack = new ArrayStack<>();
        System.out.println(stack.push(1));
        System.out.println(stack.push(2));
        System.out.println(stack.pop());
        System.out.println(stack.push(3));
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.push(4));
        System.out.println(stack.size());
    }
}
